/*LICENSE_BEGIN
 * ******************************************************************
 * Copyright 2006 by the Dainamite Robocup-Team at the
 * DAI-Labor, TU-Berlin (www.dai-labor.de)
 * 
 * Members of Dainamite are:
 * Holger Endert
 * Robert Wetzker
 * Thomas Karbe
 * Axel Heßler
 * Philippe Bütter
 * Felix Brossmann
 * 
 * Licensed under the GNU GPL (General Public License) Free Software 
 * License, Version 2. You may use this file only in compliance with 
 * the License. You may obtain a copy of the License at:
 * 
 * http://www.fsf.org/licensing/licenses/gpl.txt
 * ******************************************************************
LICENSE_END*/
/**
 * 
 */
package robocup.component.worldmodel.particlefilter;

import java.util.Random;

import robocup.component.geometry.Vektor;
import robocup.component.infotypes.BallInfo;

/**
 * @author werwurm
 * 
 */
public class BallRegion {

	private Vektor origin;

	protected double minDistance;

	protected double maxDistance;

	protected double minDirection;

	private double directionDelta;

	private Vektor helperVektor = new Vektor();

	private Random random = new Random(System.currentTimeMillis());

	/**
	 * A region, in which the ball may be located.
	 */
	public BallRegion() {

	}

	public void reinitRegionPos(BallInfo bi, double headAngle, Vektor myPos) {
		this.origin = myPos;

		this.minDistance = Math
				.log(((double) Math.rint(bi.getDistance() / 0.1) - 0.5) * 0.1);
		this.minDistance = Math
				.exp(((double) Math.rint(this.minDistance / 0.1) - 0.5) * 0.1);
		this.maxDistance = Math
				.log(((double) Math.rint(bi.getDistance() / 0.1) + 0.5) * 0.1);
		this.maxDistance = Math
				.exp(((double) Math.rint(this.maxDistance / 0.1) + 0.5) * 0.1);

		this.minDirection = bi.getDirection() + headAngle - 1;
		this.directionDelta = 2.0;
	}

	public Vektor makeRandomInsideRegion(Vektor point) {
		if (point == null)
			point = new Vektor();

		point.setLength(this.minDistance
				+ (this.maxDistance - this.minDistance)
				* this.random.nextDouble());
		point.rotate(-point.getAngle() + this.minDirection
				+ (2 * this.random.nextDouble()));
		return point.addToThis(this.origin);
	}

	public void setOrigin(Vektor origin) {
		this.origin = origin;
	}

	public double insideRegion(Vektor point) {
		this.helperVektor.x = point.x;
		this.helperVektor.y = point.y;
		this.helperVektor.subFromThis(this.origin);
		this.helperVektor.rotate(-this.minDirection);
		if (this.helperVektor.getAngle() <= this.directionDelta
				&& this.helperVektor.getAngle() >= 0
				&& this.helperVektor.getLength() >= this.minDistance
				&& this.helperVektor.getLength() <= this.maxDistance) {
			return 1.0;
		} else
			return -1;
	}

}
